from urllib.parse import parse_qs

import eventlet as eventlet_

from apps.settingApi.api.users.model import onLineModel
from comm.openDbConfig import openDbBase
from comm.dbConnect import get_yun_session

from engineio.async_drivers import eventlet

eventlet_.monkey_patch()

import socketio
import eventlet.wsgi
sio = socketio.Server(async_mode='eventlet', cors_allowed_origins='*')  # 指明在evenlet模式下

@sio.event
def connect(sid, environ):
    # 获取当前所有连接的用户sid列表
    ioDb = get_yun_session()
    print(f"连接用户, sid={sid}, environ={environ}")
    # 给定的参数字符串
    params_str = environ['QUERY_STRING']
    if "user_id" not in params_str:
        return
    # 使用parse_qs解析参数字符串
    params_dict = parse_qs(params_str)
    params_dict_single_values = {k: v[0] for k, v in params_dict.items()}
    onLineAll = []
    try:
        onLineAll = ioDb.query(onLineModel).filter(onLineModel.user_id==params_dict_single_values['user_id']).all()
    except Exception as e:
        ioDb.close()
        print('查询在线用户异常',repr(e))
    # 删除在线用户并且推送消息提醒
    for itm in onLineAll:
        try:
            deleteOnLine = ioDb.query(onLineModel).filter(onLineModel.id==itm.id).first()
            ioDb.delete(deleteOnLine)
            ioDb.commit()
        except Exception as e:
            ioDb.close()
            print('强制退出用户失败', repr(e))
        print('推送用户' + itm.id)
        sio.emit('loginout', {'msg': '其他设备登录强制退出'}, room=itm.id)
    # 增加租户在线用户
    onLineData = {}
    onLineData['id'] = sid
    onLineData['user_id'] = params_dict_single_values['user_id']
    onLineData['lessees_id'] = params_dict_single_values['lessees_id']
    onLineData['username'] = params_dict_single_values['username']
    onLineData['token'] =  params_dict_single_values['token']
    onLineData['ip'] = '1434'
    try:
        add = onLineModel(**onLineData)
        ioDb.add(add)
        ioDb.commit()
    except Exception as e:
        ioDb.rollback()
        ioDb.close()
        print('新增在线用户异常',repr(e))
@sio.event
def disconnect(sid):
    print('用户退出连接 ', sid)
    ioDb = get_yun_session()
    try:
        onLine = ioDb.query(onLineModel).filter(onLineModel.id == sid).first()
    except Exception as e:
        ioDb.close()
        print(repr(e))
        return
    if onLine != None:
        ioDb.delete(onLine)
        ioDb.commit()
    # 关闭连接
    # sio.disconnect(sid)

# 服务端强制退出
@sio.on('serveLoginOut')
def serveLoginOut(sid, data):
    print('收到服务端推送消息:', data)
    sio.emit('loginout', {'msg': '其他设备登录强制退出'}, room=data['sid'])

@sio.on('hello')
def hello(sid, data):
    print("-----")
    print(type(sid))
    print('收到消息:', data)
    # print(data.get("data"))
    # sio.emit('world', {'data': 'world'})
def start():
    config = openDbBase()
    app = socketio.Middleware(sio)
    eventlet.wsgi.server(eventlet.listen(('0.0.0.0', config["SCOKETIOPORT"])), app)
if __name__ == '__main__':
    start()